package com.topisv.tms.web.stock.instorage;

import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springside.modules.web.Servlets;

import com.topisv.tms.entity.AreaGroup;
import com.topisv.tms.entity.EdiGoodsSku;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.JSONParam;
import com.topisv.tms.entity.QueryParamHolder;
import com.topisv.tms.entity.SubWarehouseRel;
import com.topisv.tms.entity.User;
import com.topisv.tms.entity.stock.instorage.InstorageBill;
import com.topisv.tms.entity.stock.instorage.InstorageCountItem;
import com.topisv.tms.entity.stock.instorage.InstorageCountTask;
import com.topisv.tms.entity.stock.instorage.InstorageLog;
import com.topisv.tms.entity.stock.instorage.InstorageUpTaskItem;
import com.topisv.tms.entity.stock.instorage.pre.InstorageBillItemPre;
import com.topisv.tms.entity.stock.instorage.pre.InstorageBillPre;
import com.topisv.tms.entity.stock.oustorage.OutstorageBillItem;
import com.topisv.tms.entity.work.WorkBatch;
import com.topisv.tms.entity.work.WorkOrder;
import com.topisv.tms.entity.work.ExceptionOrder.ExceptionOrder;
import com.topisv.tms.repository.stock.instorage.InstorageCountItemDao;
import com.topisv.tms.repository.stock.instorage.InstorageLogDao;
import com.topisv.tms.service.EdiGoodsSkuService;
import com.topisv.tms.service.SubWarehouseRelService;
import com.topisv.tms.service.account.AccountService;
import com.topisv.tms.service.account.ShiroDbRealm.ShiroUser;
import com.topisv.tms.service.stock.instorage.InstorageBillService;
import com.topisv.tms.service.stock.instorage.InstorageCountTaskService;
import com.topisv.tms.service.stock.instorage.InstorageLogService;
import com.topisv.tms.service.stock.instorage.InstorageUpTaskService;
import com.topisv.tms.service.stock.outstorage.OutstorageBillItemService;
import com.topisv.tms.service.stock.preinstorage.PreInstorageService;
import com.topisv.tms.service.work.WorkOrderService;
import com.topisv.tms.tools.ExcelUtils;
import com.topisv.tms.utils.JsonUtil;
import com.topisv.tms.utils.enums.StatusEnums;
import com.topisv.tms.utils.rule.TMSTransportRule;
import com.topisv.tms.utils.vo.PreInstorageVo;
import com.topisv.tms.web.base.BaseDataTableController;

/**
 * 入库_control
 * @author ch
 */
@Controller
@RequestMapping(value = "/instorageBill")
public class InstorageBillController extends BaseDataTableController{

	private static final Logger logger = LoggerFactory.getLogger(InstorageBillController.class);

	@Autowired
	private InstorageBillService instorageBillService;
	@Autowired
	private AccountService accountService;
	@Autowired
	private InstorageCountTaskService instorageCountTaskService;
	@Autowired
	private InstorageCountItemDao instorageCountItemDao;
	@Autowired
	private PreInstorageService preInstorageService;
	@Autowired
	private OutstorageBillItemService outstorageBillItemService;
	@Autowired
	private InstorageUpTaskService instorageUpTaskService;
	@Autowired
	private SubWarehouseRelService subWarehouseRelService;
	@Autowired
	private WorkOrderService workOrderService;
	@Autowired
	private InstorageLogService instorageLogService;
	@Autowired
	private EdiGoodsSkuService ediGoodsSkuService ; 
	/**
	 * 导向入库单列表页面
	 * @param model
	 * @param request
	 * @return 
	 */
	@RequestMapping(value = "v2_toInstorageBillListPage")
	public String toInstorageBillListPage(Model model) {
		try {
			fillSelectValue(model, null);
		} catch (Exception e) {
			log.error("error",e);
		}
		return "instorage/instorageBillList";
	}
	
	/**
	 * 查询入库单
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "queryInstorageBill",method=RequestMethod.POST)
	public void queryInstorageBill(@RequestBody JSONParam[] paramJson, HttpServletRequest request,HttpServletResponse response) {
		try {
			QueryParamHolder paramHolder = collectParam(paramJson,"_");
			//查询入库单
			Page<InstorageBill> page = this.instorageBillService.loadPageByParam(paramHolder.getSearchParams(),paramHolder.getCurPage(), paramHolder.getPageSize());
			response.getWriter().print(bulidJSON(page));
		} catch (Exception e) {
			
			log.error("error",e);
		}
	}
	
	/**
	 * 查询分仓
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "querySubWarehouse",method=RequestMethod.POST)
	public void querySubWarehouse(@RequestParam String billId,Model model,HttpServletResponse response) {
		JSONObject json=null;
		PrintWriter out=null;
		try {
			out=response.getWriter();
			json=new JSONObject();
			
			InstorageBill instorageBill = instorageBillService.loadBillById(Long.valueOf(billId));
			if(instorageBill==null){
				json.put("status", "fail");
				out.print(json.toString());
			}
			//获取子仓
			List<SubWarehouseRel> swrList = subWarehouseRelService.findByMainWarehouseCode(instorageBill.getInwarehouseCode());
			
			fillSelectValue(model, instorageBill.getCustomerCode());
			
			List<AreaGroup> displayWarehouseList = new ArrayList<AreaGroup>();
			List<AreaGroup>  warehouseList = (List<AreaGroup>)model.asMap().get("warehouseList");
			for(AreaGroup areaGroup:warehouseList) {
				boolean result = false;
				if(areaGroup.getGroupCode().equals(instorageBill.getInwarehouseCode())){
					result = true;
				}else {
					for(SubWarehouseRel r:swrList){
						if(r.getSubWarehouseCode()!=null && r.getSubWarehouseCode().equals(areaGroup.getGroupCode())){
							result = true;
							break;
						}
					}
				}
				if(result) {
					displayWarehouseList.add(areaGroup);
				}
			}
			json.put("warehouseList", displayWarehouseList);
			json.put("status", "success");
			out.print(json.toString());
			log.debug("分配主仓编码:"+json.toString());
		} catch (Exception e) {e.printStackTrace();
			log.error("error",e);
		}
	}
	
	/**
	 * 删除入库单
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "ajaxDelete")
	@ResponseBody
	public String ajaxDelete(ServletRequest request) {
		try {
			Long billId=Long.valueOf(request.getParameter("billId"));
			this.instorageBillService.deleteBill(billId);
			return "true";
		} catch (Exception e) {
			log.error("error",e);
			return "false";
		}
	}
	
	
	/**
	 * 取消入库单
	 *
	 * @param 
	 * @return 
	 * @throws 
	 * @author yuansheng
	 * @version 1.0.0
	 */
	@RequestMapping(value = "ajaxCancel")
    @ResponseBody
    public Object ajaxCancel(Long billId) {
	    JSONObject json = new JSONObject();
        try {
            int state = instorageBillService.cancelBill(billId);
            if(state == 1){
                json.put("status", state);
                json.put("content", "取消成功");
            } else if (state == 0) {
                json.put("status", state);
                json.put("content", "订单状态不为待登记或入库登记");
            }
            return json;
        } catch (Exception e) {
            log.error("取消入库单异常",e);
            json.put("status", 0);
            json.put("content","服务器异常");
            return json;
        }
    }
	
	
	@RequestMapping("v2_queryInstorageCountCompareInfo")
	public String queryInstorageCountCompareInfo(@RequestParam String billCode,Model model){
		InstorageBill instorageBill = instorageBillService.loadBillByCode(billCode);
		List<InstorageCountItem> countItemList = instorageCountItemDao.loadByBillCode(billCode);
		Map<String,Integer> countMap = new HashMap<String,Integer>();
		for(InstorageCountItem ict : countItemList)
		{
			countMap.put(ict.getSku(), ict.getNum());
		}
		//model.addAttribute("countItemList", countItemList);
		model.addAttribute("billType", instorageBill.getBillType());
		
		if ("preOrder".equals(instorageBill.getBillType())) {
			PreInstorageVo vo = preInstorageService.queryPreInstorageVo(instorageBill.getPreBill().getId());
			List<InstorageBillItemPre> list = vo.getInstorageBillItemPres();
			for(InstorageBillItemPre pre : list)
			{
				pre.setCountNum(countMap.get(pre.getSkuCode()));
			}
			model.addAttribute("preOrder", vo);
		} else if ("allot".equals(instorageBill.getBillType())) {
			List<OutstorageBillItem> obi = outstorageBillItemService.loadByBillCode(instorageBill.getAboutCode());
			for(OutstorageBillItem pre : obi)
			{
				pre.setCountNum(countMap.get(pre.getSku()));
			}
			model.addAttribute("allotItemList",obi);
		}
		return "instorage/instorageCountCompare";
	}
	/**
	 * 创建or修改入库单
	 * @param bill
	 * @return
	 */
	@RequestMapping(value = "ajaxCreateOrUpdate")
	@ResponseBody
	public String ajaxCreateOrUpdate(ServletRequest request) {
		try {
			
			String idStr=request.getParameter("id");
			
			if(StringUtils.isBlank(idStr)){  //添加
				InstorageBill bill=new InstorageBill();
				
				//入库单类型 (1.采购入库  2.调拨入库 )
				String billType=request.getParameter("billType");
				bill.setBillType(billType); 

				//入库单号(编码规则：'RK'+时间,例如：RK201309091212004 )
				bill.setBillCode(TMSTransportRule.generateInStorageBillCode());
				
				//相关单号 （调拨入库->调拨单号）
				String aboutCode=request.getParameter("aboutCode");
				bill.setAboutCode(aboutCode);
				
				//商户信息
				String customerCode=request.getParameter("customerCode");
				bill.setCustomerCode(customerCode);
				
				//入库仓库信息
				String inwarehouseCode=request.getParameter("inwarehouseCode");
				bill.setInwarehouseCode(inwarehouseCode);
				
				//备注
				String remarks=request.getParameter("remarks");
				bill.setRemarks(remarks);
				
				//创建人
				User user=accountService.getUser(getCurrentUserId());
				bill.setCreaterUuid(user.getJobuuid());
				
				//入库时间
				bill.setCreateTime(new Date());
				
				//入库状态 （0:待登记 (调拨货品已出库，尚未入库) 1.入库登记 2.领取点收任务 3.点收完成 4.领取上架任务 5.上架完成 ）
				bill.setStatus("1");
				
				//是否破损件
				bill.setErrorFlag(request.getParameter("errorFlag"));
				
				// 标记订单是否可以取消 419 yuangsheng
				// 是否可以取消
				bill.setCancelFlag(1);
				// 标记订单是否可以取消 419 yuangsheng
				
				this.instorageBillService.createNewBill(bill);
				
			}else{ //修改
				Long billId=Long.valueOf(idStr);
				InstorageBill bill=this.instorageBillService.loadBillById(billId);
				
				//相关单号 （调拨入库->调拨单号）
				String aboutCode=request.getParameter("aboutCode");
				bill.setAboutCode(aboutCode);
				
				//备注
				String remarks=request.getParameter("remarks");
				bill.setRemarks(remarks);
				
				this.instorageBillService.saveBill(bill);
			}
			
			return "true";
			
		} catch (Exception e) {
			
			log.error("error",e);
			return "false";
		}
	}
	
	/**
	 * 修改入库单信息
	 * @param bill
	 * @param redirectAttributes
	 */
	@RequestMapping(value = "update", method = RequestMethod.POST)
	public String update(@Valid InstorageBill bill, RedirectAttributes redirectAttributes){
		
		InstorageBill _bill=this.instorageBillService.loadBillById(bill.getId());
		_bill.setBoxNum(bill.getBoxNum());
		_bill.setSkuNum(bill.getSkuNum());
		_bill.setGoodsNum(bill.getGoodsNum());
		_bill.setRemarks(bill.getRemarks());
		_bill.setAboutCode(bill.getAboutCode());
		
		this.instorageBillService.saveBill(_bill);
		return "redirect:/cusInstorageBill";
	}
	
	@RequestMapping(value = "v2_createInBillAgain", method = RequestMethod.POST)
	@ResponseBody
	public String createInBillAgain(@RequestParam("id") Long billId){
		try {
			instorageBillService.createInBillAgain(billId);
			return "true";
		} catch (Exception e) {
			logger.error("error",e);
			return "false";
		}
	}
	
	/**
	 * ajax获得订单
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "ajaxGetBill")
	public String ajaxGetBill(ServletRequest request,HttpServletResponse response) {
		try {	
			Long billId=Long.valueOf(request.getParameter("billId"));
			InstorageBill bill=this.instorageBillService.loadBillById(billId);
			
			String json = JsonUtil.getObjectString(bill);
			PrintWriter out;
			out = response.getWriter();
			out.print(json);
		
		} catch (Exception e) {
			log.error("error",e);
		}
		return null;
	}
	
	
	/**
	 * 确认登记
	 * @param bill
	 * @return
	 */
	@RequestMapping(value = "ajaxConfirmIn")
	@ResponseBody
	public String ajaxConfirmIn(ServletRequest request) {
		try {
			Long billId=Long.valueOf(request.getParameter("billId")+"");
			String selectedWarehouseCode=request.getParameter("selectedWarehouseCode");
			this.instorageBillService.confirmIn(billId,selectedWarehouseCode);
			return "true";
		} catch (Exception e) {
			log.error("error",e);
			return "false";
		}
	}
	/**
	 * 重发奇门接口
	 * @param bill
	 * @return
	 */
	@RequestMapping(value = "repeatSendQM")
	@ResponseBody
	public String repeatSendQM(ServletRequest request) {
		try {
			Long billId=Long.valueOf(request.getParameter("billId")+"");
			this.instorageBillService.repeatSendQM(billId);
			return "true";
		} catch (Exception e) {
			log.error("error",e);
			return "false";
		}
	}
	
	/**
	 * 导向入库单明细页面
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "v2_toInstorageBillDetailPage/{billCode}")
	public String toInstorageBillDetailPage(@PathVariable("billCode")String billCode,Model model) {
		try {
			
			//入库单
			InstorageBill inBill=this.instorageBillService.loadBillByCode(billCode);
			model.addAttribute("inBill", inBill);
			
			//点收任务
			InstorageCountTask countTask=this.instorageCountTaskService.loadByBillCode(billCode);
			model.addAttribute("countTask", countTask);
			
			//点收明细
			List<InstorageCountItem> countItemList=this.instorageCountItemDao.loadByBillCode(billCode);
			for(InstorageCountItem item:countItemList){
				item.setEdiGoodsSku(ediGoodsSkuService.findByCustomerCodeAndSku(item.getCustomerCode(),item.getSku()));
			}
			model.addAttribute("countItemList", countItemList);
			//上架明细
			List<InstorageUpTaskItem> upItemList=instorageUpTaskService.loadByBillCode(billCode);
			for(InstorageUpTaskItem item:upItemList){
				item.setEdiGoodsSku(ediGoodsSkuService.findBySkuAndCustomerCode(item.getSkuCode(),inBill.getCustomerCode()));
			}
			model.addAttribute("upItemList", upItemList);
			//入库日志
			List<InstorageLog> logList = instorageLogService.loadLogByBillCode(billCode);
			model.addAttribute("logList",logList);
			
		} catch (Exception e) {
			
			log.error("error",e);
		}
		return "stock/instorage/instorageBillDetail";
	}
	

	private Long getCurrentUserId() {
		ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
		return user.id;
	}
	
	/**
	 * 导出退货入库单
	 * @param model
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "outReturnExcel")
	public void outReturnExcel(ServletRequest request, HttpServletResponse response) throws Exception {
		Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, "_");
		String fromTm = (String)searchParams.get("fromDate");
		String toTm = (String)searchParams.get("toDate");
		Date fromDate=null;
		Date toDate=null;
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		if(StringUtils.isNotEmpty(fromTm)){
			fromDate=sdf.parse(fromTm+" 00:00:00");
		}
		if(StringUtils.isNotEmpty(toTm)){
			toDate=sdf.parse(toTm+" 23:59:59");
		}
		String warehouseCode=(String)searchParams.get("warehouseCode");
		String customerCode=(String)searchParams.get("customerCode");
		
		Map<String, Object> param = new HashMap<String, Object>();
		
		param.put("billType", "returnOrder");
		param.put("aboutCode", "PRE");
		param.put("customerCode", customerCode);
		param.put("warehouseCode", warehouseCode);
		param.put("fromDate", fromDate);
		param.put("toDate", toDate);
		List<InstorageBill> insorageBills = instorageBillService.findInstorageBill(param);
		log.info("=======开始导出退货入库单=======");
		
		response.setContentType("application/vnd.ms-excel");
		response.setHeader("Content-disposition","attachment; filename=" + customerCode +fromTm + toTm+ ".xls");
		
        DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
		String[] titles = {"日期","客户","配货单号","退回单号","SKU","退货原因","是否已上架"};
		List<Object[]> rs = new ArrayList<Object[]>();
		for(InstorageBill bill:insorageBills){
			List<WorkOrder> orders =new ArrayList<WorkOrder>();;
			InstorageBillPre billPre = instorageBillService.findByBillCode(bill.getAboutCode());
			if(!"".equals(billPre.getOldCusOrderNo())||billPre.getOldCusOrderNo()!=null){
				orders = workOrderService.findByFromno(billPre.getOldCusOrderNo());
			}
			List<InstorageBillItemPre> items = instorageBillService.findByBillPreId(billPre.getId());
			StringBuffer good = new StringBuffer("");
			for(InstorageBillItemPre itemPre : items){
				good.append(itemPre.getSkuCode()).append("(").append(itemPre.getGoodsNum()).append(")").append("  ");
			}
			String orderstatus = "否";
			if("5".equals(bill.getStatus())){
				orderstatus = "是";
			}
			String recena = "";
			if(orders.size() != 0){
				recena = orders.get(0).getOrder().getRecena();
			}
					Object[] object = {
							df.format(billPre.getCreateTm()),
							recena,
							billPre.getOldCusOrderNo(),
							billPre.getExpressNo(),
							good.toString(),
							billPre.getRemark(),
							orderstatus,
							null
					};
					rs.add(object);
		}
		ExcelUtils.writeExcel(titles,"Sheet1",rs,response.getOutputStream());
        log.info("=======导出结束=======");
	}
	public static void main(String[] args) {
		StringBuffer sb = new StringBuffer("");
		System.out.println("11"+sb.toString());
	}
}
